Atcoder ABC396游记(A~E)
A.Triple Four
题目描述
给你一个长度为N N N 的数组A A A ,问你有没有3 3 3 个连续且相同的元素?
思路
感觉不用讲
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <bits/stdc++.h> using namespace std;int main () { int n; cin >> n; vector<int > a (n) ; for (int i = 0 ; i < n; i++) { cin >> a[i]; } for (int i = 0 ; i < n - 2 ; i++) { if (a[i] == a[i + 1 ] && a[i + 1 ] == a[i + 2 ]) { cout << "Yes" ; return 0 ; } } cout << "No" ; return 0 ; }
B.Card Pile
题目描述
给你一个栈,最初有100 100 1 0 0 个0 0 0 在里面。支持2 2 2 种操作:
1 x
往栈顶放一个元素x x x 。
2
输出栈顶元素,并且把栈顶元素移除。
思路
感觉不用讲
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <bits/stdc++.h> using namespace std;int main () { stack<int > st; for (int i = 1 ; i <= 100 ; i++) { st.push (0 ); } int q; cin >> q; while (q--) { int ch; cin >> ch; if (ch == 1 ) { int x; cin >> x; st.push (x); } else { cout << st.top () << '\n' ; st.pop (); } } return 0 ; }
C.Buy Balls
题目描述
有N N N 个白球,M M M 个黑球,每个球上面都写了一个数。
第i i i 个白球上面写的数字是W i W_i W i 。
第i i i 个黑球上面写的数字是B i B_i B i ,
思路
贪心就刑 好奇有没有用dp做出来的神犇
没错但是我还是被这题卡了一下 但是问题不大
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <bits/stdc++.h> using namespace std;#define ll long long int main () { int n, m; cin >> n >> m; vector<ll> b (n) ; for (int i = 0 ; i < n; ++i) { cin >> b[i]; } sort (b.rbegin (), b.rend ()); vector<ll> w (m) ; for (int i = 0 ; i < m; ++i) { cin >> w[i]; } sort (w.rbegin (), w.rend ()); vector<ll> b_sum (n + 1 , 0 ) ; for (int i = 1 ; i <= n; ++i) { b_sum[i] = b_sum[i - 1 ] + b[i - 1 ]; } vector<ll> w_sum (m + 1 , 0 ) ; for (int i = 1 ; i <= m; ++i) { w_sum[i] = w_sum[i - 1 ] + w[i - 1 ]; } vector<ll> maxB (n + 1 ) ; maxB[n] = b_sum[n]; for (int k = n - 1 ; k >= 0 ; --k) { maxB[k] = max (b_sum[k], maxB[k + 1 ]); } ll res = 0 ; int max_t = min (m, n); for (int t = 0 ; t <= max_t ; ++t) { ll current = w_sum[t] + maxB[t]; if (current > res) { res = current; } } cout << res; return 0 ; }
D.Minimum XOR Path
题目描述
给你一个简单的连通无向图,包含 N N N 个顶点,编号从 1 1 1 到 N N N ,以及 M M M 条边,编号从 1 1 1 到 M M M 。边 i i i 连接顶点 u i u_i u i 和 v i v_i v i ,并且具有标签 w i w_i w i 。
在从顶点 1 1 1 到顶点 N N N 的所有简单路径(即不经过相同顶点超过一次的路径)中,找到路径上边的标签的最小异或值。
关于异或(XOR)的说明: 对于非负整数 A A A 和 B B B ,它们的异或 A ⊕ B A \oplus B A ⊕ B 定义如下:
在 A ⊕ B A \oplus B A ⊕ B 的二进制表示中,对应于 2 k , ( k ≥ 0 ) 2^k ,(k \ge 0) 2 k , ( k ≥ 0 ) 的位为 1 1 1 当且仅当 A A A 和 B B B 的相同位置的位中恰好有一个为 1 1 1 ;否则,该位为 0 0 0 。
例如,3 ⊕ 5 = 6 3 \oplus 5 = 6 3 ⊕ 5 = 6 (在二进制中:011 ⊕ 101 = 110 011 \oplus 101 = 110 0 1 1 ⊕ 1 0 1 = 1 1 0 )。 一般而言,k k k 个整数 p 1 , … , p k p_1, \dots, p_k p 1 , … , p k 的异或定义为 ( ⋯ ( ( p 1 ⊕ p 2 ) ⊕ p 3 ) ⊕ ⋯ ⊕ p k ) (\cdots ((p_1 \oplus p_2) \oplus p_3) \oplus \cdots \oplus p_k) ( ⋯ ( ( p 1 ⊕ p 2 ) ⊕ p 3 ) ⊕ ⋯ ⊕ p k ) 。可以证明,它不依赖于 p 1 , … , p k p_1, \dots, p_k p 1 , … , p k 的顺序。
思路
你看,你看这个N N N 啊,才最大到10 10 1 0 ,真的太逊了
时间限制也是2 2 2 秒,也是很逊啊
所以不用想太多,直接DFS
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h> using namespace std;#define int long long int n, m;vector<vector<pair<int , int >>> edges; int ans;void dfs (int u, int cur, int vis) { if (u == n) { if (cur < ans) { ans = cur; } return ; } for (const auto & edge : edges[u]) { int v = edge.first; int w = edge.second; if (!(vis & (1 << v))) { int nex = vis | (1 << v); int nexx = cur ^ w; dfs (v, nexx, nex); } } } signed main () { cin >> n >> m; edges.resize (n + 1 ); for (int i = 0 ; i < m; ++i) { int u, v, w; cin >> u >> v >> w; edges[u].emplace_back (v, w); edges[v].emplace_back (u, w); } ans = LLONG_MAX; dfs (1 , 0 , 1 << 1 ); cout << ans; return 0 ; }
E.Min of Restricted Sum
题目描述
给你整数 N N N 和 M M M ,以及三个长度为 M M M 的整数序列:X = ( X 1 , X 2 , … , X M ) X = (X_1, X_2, \ldots, X_M) X = ( X 1 , X 2 , … , X M ) ,Y = ( Y 1 , Y 2 , … , Y M ) Y = (Y_1, Y_2, \ldots, Y_M) Y = ( Y 1 , Y 2 , … , Y M ) ,和 Z = ( Z 1 , Z 2 , … , Z M ) Z = (Z_1, Z_2, \ldots, Z_M) Z = ( Z 1 , Z 2 , … , Z M ) 。保证 X X X 和 Y Y Y 中的所有元素都在 1 1 1 到 N N N 之间(包括 1 1 1 和 N N N )。
我们称一个长度为 N N N 的非负整数序列 A = ( A 1 , A 2 , … , A N ) A = (A_1, A_2, \ldots, A_N) A = ( A 1 , A 2 , … , A N ) 为好序列,当且仅当它满足以下条件:
对于每一个整数 i i i ,满足 1 ≤ i ≤ M 1 \le i \le M 1 ≤ i ≤ M ,A X i A_{X_i} A X i 和 A Y i A_{Y_i} A Y i 的异或值等于 Z i Z_i Z i 。
判断是否存在一个好序列 A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\ldots,A_N) A = ( A 1 , A 2 , … , A N ) ,如果存在,找到一个好序列,使其元素之和 ∑ i = 1 N A i \displaystyle \sum_{i=1}^N A_i i = 1 ∑ N A i 最小。
关于异或(XOR)的说明: 对于非负整数 A A A 和 B B B ,它们的异或 A ⊕ B A \oplus B A ⊕ B 定义如下:
在 A ⊕ B A \oplus B A ⊕ B 的二进制表示中,对应于 2 k , ( k ≥ 0 ) 2^k ,(k \ge 0) 2 k , ( k ≥ 0 ) 的位为 1 1 1 当且仅当 A A A 和 B B B 的相同位置的位中恰好有一个为 1 1 1 ;否则,该位为 0 0 0 。
例如,3 ⊕ 5 = 6 3 \oplus 5 = 6 3 ⊕ 5 = 6 (在二进制中:011 ⊕ 101 = 110 011 \oplus 101 = 110 0 1 1 ⊕ 1 0 1 = 1 1 0 )。
思路
我们搞一个并查集维护它到父节点的异或路径。
如何判断是不是− 1 -1 − 1 ?我们可以通过在输入约束的时候同时用并查集判断有没有矛盾。
然后我们从高位到低位确定答案,保证小
然后,我不知道该写啥
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #include <bits/stdc++.h> using namespace std;vector<int > fa; vector<int > xorp; void init (int n) { fa.resize (n); xorp.resize (n, 0 ); for (int i = 0 ; i < n; ++i) { fa[i] = i; } } int find (int x) { if (fa[x] != x) { int orfa = fa[x]; fa[x] = find (fa[x]); xorp[x] ^= xorp[orfa]; } return fa[x]; } bool unite (int x, int y, int z) { int rx = find (x); int ry = find (y); int xorx = xorp[x]; int xory = xorp[y]; if (rx == ry) { return (xorx ^ xory) == z; } else { fa[rx] = ry; xorp[rx] = xorx ^ xory ^ z; return true ; } } int main () { int n, m; cin >> n >> m; vector<int > x (m) , y (m) , z (m) ; for (int i = 0 ; i < m; ++i) { cin >> x[i] >> y[i] >> z[i]; x[i]--; y[i]--; } init (n); bool flag = true ; for (int i = 0 ; i < m; ++i) { if (!unite (x[i], y[i], z[i])) { flag = false ; break ; } } if (!flag) { cout << -1 ; return 0 ; } unordered_map<int , vector<int >> groups; for (int i = 0 ; i < n; ++i) { find (i); int root = fa[i]; groups[root].push_back (i); } vector<long long > a (n, 0 ) ; for (auto & [root, nodes] : groups) { vector<int > cnt0 (31 , 0 ) , cnt1 (31 , 0 ) ; for (int i : nodes) { int x = xorp[i]; for (int k = 0 ; k < 31 ; ++k) { if ((x >> k) & 1 ) { cnt1[k]++; } else { cnt0[k]++; } } } long long root_val = 0 ; for (int k = 30 ; k >= 0 ; --k) { if (cnt1[k] >= cnt0[k]) { root_val |= (1LL << k); } } for (int i : nodes) { a[i] = root_val ^ xorp[i]; } } for (int i = 0 ; i < n; ++i) { cout << a[i] << ' ' ; } return 0 ; }
总结
我不知道写啥啊
来娱乐亿下
一个TB的oier写的文章
原作者
原文洛谷链接
本站链接
今天是38妇女节,祝每一位妇女节日快乐,rp++!
(怎么写的书面一点我不到啊)